#include "FrontCoder.h"
#include "../BTree/RegistroDatos.h"
#include "../BTree/RegistroComprimidoDatos.h"

#include <typeinfo>


FrontCoder::FrontCoder(){
}

FrontCoder::~FrontCoder() {
}


// Comprime el listado de registros de datos comprimidos
void FrontCoder::encode(NodoDatos& nodo){
	// Para el front coding se necesita guardar la clave anterior
	std::string claveAnterior = "";

	// Lo que hace es actualizar el listado de registros seteando sus claves comprimidas
	std::list<IRegistro*>::iterator it;
	for (it = nodo.lRegistros.begin(); it != nodo.lRegistros.end(); ++it){

		if (typeid(**it) != typeid(RegistroComprimidoDatos)){
			throw std::runtime_error("El front coder solo recibe listas de punteros a registros de datos comprimidos");
		}

		RegistroComprimidoDatos* rTemp = static_cast<RegistroComprimidoDatos*>(*it);

		// Se comprime el registro
		std::string clave = rTemp->getClave(claveAnterior);
		rTemp->setClaveComprimida(clave, claveAnterior);
		claveAnterior = clave;
	}
}


// Convierte el listado de registros comprimidos en registros de datos
void FrontCoder::decode(NodoDatos& nodo){
	std::string claveAnterior = "";

	// Recorre la lista de regitros y los descomprime de a uno
	std::list<IRegistro*>::iterator it;
	for (it = nodo.lRegistros.begin(); it != nodo.lRegistros.end(); ++it){

		// Solo se descomprimen registros de front coding
		if (typeid(**it) != typeid(RegistroComprimidoDatos)){
			throw std::runtime_error("El front decoder solo recibe listas de punteros a registros de datos comprimidos");
		}

		RegistroComprimidoDatos* r = static_cast<RegistroComprimidoDatos*>(*it);

		// Mediante la clave anterior se descomprime la clave completa y la vuelvo a settear
		std::string clave = r->getClave(claveAnterior);
		r->setClave(clave);	// Según la implementación interna esto no es necesario, pero el front coder no lo sabe, asi que...

		claveAnterior = clave;
	}
}


